/*
 * Copyright © 2009 Perseus Project - Tufts University <http://www.perseus.tufts.edu>
 *
 * This file is part of UniCollatorPerseus.
 *
 * OcroPerseus is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * OcroPerseus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with OcroPerseus.  If not, see <http://www.gnu.org/licenses/>.
 */

//TODO This class must be totally redone!

package eu.himeros.ocr.hocr;

import eu.himeros.transcoder.Transcoder;

/**
 * Mix ground truth word and OCR word.
 *
 * @author Federico Boschetti <federico.boschetti.73@gmail.com>
 */
public class WordMixer {
    String gtWord;
    String ocrWord;
    String gtBody="";
    String ocrBody="";
    String res="";
    int leftGtBound=0;
    int rightGtBound=0;
    int leftOcrBound=0;
    int rightOcrBound=0;
    final String markers="[\"'\u2020\u0387\u2019,;:\\-\\.\\[\\]\\(\\)\\{\\}\\<\\>]";
    final String wd="/home/federico/tmp/";
    Transcoder transUp=new Transcoder(wd+"low2up.txt");
    Transcoder transOcr=new Transcoder(wd+"ocr2grk.txt");
    Transcoder transBeta=new Transcoder(wd+"beta2u.txt");
    static int counter=0;

    /**
     * Default Constructor.
     */
    public WordMixer(){}

    /**
     * Merges ground truth word with OCR word.
     * @param gtWord the ground truth word.
     * @param ocrWord the OCR word.
     * @return the merged word.
     */
    public String merge(String gtWord, String ocrWord){
        leftGtBound=0;
        rightGtBound=0;
        leftOcrBound=0;
        rightOcrBound=0;
        this.gtWord=gtWord;
        this.ocrWord=ocrWord;
        rightGtBound=gtWord.length();
        rightOcrBound=ocrWord.length();
        //strip left markers
        for(int i=0;i<gtWord.length();i++){
            if((""+gtWord.charAt(i)).matches(markers)){
                leftGtBound=i+1;
            }else{
                break;
            }
        }
        for(int i=0;i<ocrWord.length();i++){
            if((""+ocrWord.charAt(i)).matches(markers)){
                leftOcrBound=i+1;
            }else{
                break;
            }
        }
        //strip right markers
        for(int i=gtWord.length()-1;i>-1;i--){
            if((""+gtWord.charAt(i)).matches(markers)){
                rightGtBound=i+1;
            }else{
                break;
            }
        }
        for(int i=ocrWord.length()-1;i>-1;i--){
            if((""+ocrWord.charAt(i)).matches(markers)){
                rightOcrBound=i+1;
            }else{
                break;
            }
        }
        gtBody=gtWord.substring(leftGtBound,rightGtBound);
        ocrBody=ocrWord.substring(leftOcrBound,rightOcrBound);
        //evaluate if it is a latin or a greek word
        if(testLatin(ocrBody)) return ocrWord;
        //transform latin letters in Greek ones (e.g. T, o...) and correct encoding (e.g. epsilon with acute)
        ocrBody=transOcr.parse(ocrBody);
        //delete bad chars inside
        ocrBody=ocrBody.replaceAll(markers,"");
        //compare upperCase words
        
        if(!transUp.parse(gtBody).equals(transUp.parse(ocrBody))){
            System.out.println("diff= "+(counter++)+" "+gtBody+"("+transUp.parse(gtBody)+") : "+ocrBody+"("+transUp.parse(ocrBody)+")");
            return makeRes();
        }else{
            System.out.println("equl= "+(counter++)+" "+gtBody+"("+transUp.parse(gtBody)+") : "+ocrBody+"("+transUp.parse(ocrBody)+")");
        }
        ocrBody=gtBody;
        return makeRes();
    }

    /**
     * Test whether the word is Latin (true) or Greek (false).
     *
     * @param str the string to be tested.
     * @return true for Latin, false for Greek.
     */
    private boolean testLatin(String str){
        double len=str.length();
        int greekChars=0;
        for(int i=0;i<str.length();i++){
            if(str.charAt(i)>256){
                greekChars++;
            }
            if(greekChars>=(len/2)) return false;
        }
        return true;
    }

    /**
     * Make the string result.
     * @return the result.
     */
    private String makeRes(){
        return ocrWord.substring(0,leftOcrBound)+ocrBody+ocrWord.substring(rightOcrBound);
    }

}
